/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-05
 * V4.0
 */
package com.jphenix.service.db.datamanager.instancea;

import com.jphenix.kernel.objectpool.instancea.ObjectElement;
import com.jphenix.service.db.datamanager.interfaceclass.IConnectionManager;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.log.ILog;

import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;



/**
 * 数据库连接池，连接对象实例 (池元素)
 * @author 刘虻
 * 2006-8-13  14:35:04
 */
@ClassInfo({"2014-06-05 13:40","数据库连接类"})
public class ConnectionImpl 
			extends ObjectElement
				implements Connection,IConnectionManager {

    protected Connection kernel = null; //连接核心实例
    
    protected String validationQuerySql = null; //验证数据库语句
    
    protected ILog log = null; //日志处理类
    
    /**
     * 构造函数 
     * @author 刘虻
     * 2006-8-13 14:35:04
     */
    public ConnectionImpl() {
        super();
    }

    /**
     * 设置日志类实例
     * @author 刘虻
     * 2007-7-5下午05:04:28
     * @param log 日志类实例
     */
    public void setLog(ILog log) {
    	this.log = log;
    }
    
    /**
     * 获取日志类实例
     * @author 刘虻
     * 2007-7-5下午05:04:45
     * @return 日志类实例
     */
    public ILog getLog() {
    	return log;
    }
    
    /**
     * 获得核心连接实例
     * @author 刘虻
     * @return 核心连接实例
     * 2006-8-13  14:38:47
     */
    public Connection getKernel() throws SQLException {
    	if(kernel==null) {
    		throw new SQLException("Connection Is Closed");
    	}
        return kernel;
    }
    
    /**
     * 设置核心连接实例
     * @author 刘虻
     * @param kernel 核心连接实例
     * 2006-8-13  14:39:17
     */
    public void setKernel(Connection kernel) {
        this.kernel = kernel;
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public int getHoldability() throws SQLException {
        return getKernel().getHoldability();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public int getTransactionIsolation() throws SQLException {
        return getKernel().getTransactionIsolation();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void clearWarnings() throws SQLException {
        getKernel().clearWarnings();
    }

    /**
     * 覆盖方法 从不让用户关闭连接对象，全部由数据库连接池管理
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void close() throws SQLException {
        freeElement();
    }

    
    
    /**
     * 覆盖方法  有数据库连接池管理
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void commit() throws SQLException {}

    /**
     * 覆盖方法 由数据库连接池管理
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void rollback() throws SQLException {}

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public boolean getAutoCommit() throws SQLException {
        return getKernel().getAutoCommit();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public boolean isClosed() throws SQLException {
    	if (getKernel()==null) {
    		return true;
    	}
        return getKernel().isClosed();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public boolean isReadOnly() throws SQLException {
        return getKernel().isReadOnly();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void setHoldability(int holdability) throws SQLException {
        getKernel().setHoldability(holdability);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void setTransactionIsolation(int level) throws SQLException {
        getKernel().setTransactionIsolation(level);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void setAutoCommit(boolean autoCommit) throws SQLException {}

    /**
     * 覆盖方法
     * @author 刘虻
     * 2006-8-26下午11:10:50
     */
    @Override
    public void doSetAutoCommit(boolean autoCommit) throws SQLException{
    	getKernel().setAutoCommit(autoCommit);
    }
    
    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void setReadOnly(boolean readOnly) throws SQLException {
        getKernel().setReadOnly(readOnly);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public String getCatalog() throws SQLException {
        return getKernel().getCatalog();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void setCatalog(String catalog) throws SQLException {
        getKernel().setCatalog(catalog);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public DatabaseMetaData getMetaData() throws SQLException {
        return getKernel().getMetaData();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public SQLWarning getWarnings() throws SQLException {
        return getKernel().getWarnings();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public Savepoint setSavepoint() throws SQLException {
        return getKernel().setSavepoint();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
        getKernel().releaseSavepoint(savepoint);
    }

    /**
     * 覆盖方法 有数据库连接池管理
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void rollback(Savepoint savepoint) throws SQLException {}

    /**
     * 处理事务信息
     * @author 刘虻
     * 2008-7-30下午01:59:27
     * @param stmt
     */
    protected Statement fixStatement(Statement stmt) {
    	if (stmt!=null) {
    		try {
    			stmt.setQueryTimeout((int)getUseTimeOut()/1000); //设置查询超时时间
    		}catch(Exception e) {}
    	}
    	return stmt;
    }
    
    
    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public Statement createStatement() throws SQLException {
    	return fixStatement(getKernel().createStatement());
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public Statement createStatement(int resultSetType, int resultSetConcurrency)
            throws SQLException {
    	return fixStatement(getKernel().createStatement(resultSetType,resultSetConcurrency));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public Statement createStatement(int resultSetType,
                                     int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
    	return fixStatement(getKernel().createStatement(
                resultSetType,resultSetConcurrency,resultSetHoldability));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public Map<String,Class<?>> getTypeMap() throws SQLException {
        return getKernel().getTypeMap();
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public void setTypeMap(Map<String,Class<?>> map) throws SQLException {
        getKernel().setTypeMap(map);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public String nativeSQL(String sql) throws SQLException {
        return getKernel().nativeSQL(sql);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public CallableStatement prepareCall(String sql) throws SQLException {
    	return (CallableStatement)fixStatement(getKernel().prepareCall(sql));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public CallableStatement prepareCall(String sql, int resultSetType,
                                         int resultSetConcurrency) throws SQLException {
    	return (CallableStatement)fixStatement(
    			getKernel().prepareCall(sql,resultSetType,resultSetConcurrency));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public CallableStatement prepareCall(String sql, int resultSetType,
                                         int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
    	return (CallableStatement)fixStatement(
    			getKernel().prepareCall(
    					sql,resultSetType,resultSetConcurrency,resultSetHoldability));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
    	return (PreparedStatement)fixStatement(getKernel().prepareStatement(sql));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
            throws SQLException {
    	return (PreparedStatement)fixStatement(getKernel().prepareStatement(sql,autoGeneratedKeys));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType,
                                              int resultSetConcurrency) throws SQLException {
    	return (PreparedStatement)fixStatement(getKernel().prepareStatement(sql,resultSetType,resultSetConcurrency));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType,
                                              int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        return (PreparedStatement)fixStatement(getKernel().prepareStatement(
                sql,resultSetType,resultSetConcurrency,resultSetHoldability));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
            throws SQLException {
        return (PreparedStatement)fixStatement(getKernel().prepareStatement(sql,columnIndexes));
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public Savepoint setSavepoint(String name) throws SQLException {
        return getKernel().setSavepoint(name);
    }

    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 14:35:04
     */
    @Override
    public PreparedStatement prepareStatement(String sql, String[] columnNames)
            throws SQLException {
        return (PreparedStatement)fixStatement(getKernel().prepareStatement(sql,columnNames));
    }






    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 15:23:02
     */
    @Override
    public void doClose() throws SQLException {
        getKernel().close();
        freeElement();
        getLog().sqlLog("[CLOSED] SessionID:["+getPK()+"]");
    }






    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 15:23:02
     */
    @Override
    public void doCommit() throws SQLException {
        getKernel().commit();
        freeElement(); 
        getLog().sqlLog("[COMMIT] SessionID:["+getPK()+"]");
    }






    /**
     * 覆盖方法 
     * @author  刘虻
     * 2006-8-13 15:23:02
     */
    @Override
    public void doRollback() throws SQLException {
        getKernel().rollback();
        freeElement(); 
        getLog().sqlLog("[ROLLBACK] SessionID:["+getPK()+"]");
    }

    

    /**
     * 覆盖方法
     * @author 刘虻
     * 2009-4-3下午12:41:37
     */
	@Override
    public Array createArrayOf(String typeName, Object[] elements)
			throws SQLException {
		return null;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:41:52
	 */
	@Override
    public Blob createBlob() throws SQLException {
		return null;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:41:59
	 */
	@Override
    public Clob createClob() throws SQLException {
		return null;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:13
	 */
	@Override
    public Struct createStruct(String typeName, Object[] attributes)
			throws SQLException {
		return null;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:18
	 */
	@Override
    public Properties getClientInfo() throws SQLException {
		return null;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:25
	 */
	@Override
    public String getClientInfo(String name) throws SQLException {
		return null;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:28
	 */
	@Override
    public boolean isValid(int timeout) throws SQLException {
		return false;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:46
	 */
	@Override
    public boolean isWrapperFor(Class<?> arg0) throws SQLException {
		return false;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:51
	 */
	@Override
    public <T> T unwrap(Class<T> arg0) throws SQLException {
		return null;
	}
	
	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:03
	 */
	@Override
    public NClob createNClob() throws SQLException {
		return null;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:09
	 */
	@Override
    public SQLXML createSQLXML() throws SQLException {
		return null;
	}
	
	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:32
	 */
	@Override
    public void setClientInfo(Properties properties)
			throws SQLClientInfoException {}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2009-4-3下午12:42:39
	 */
	@Override
    public void setClientInfo(String name, String value)
			throws SQLClientInfoException {}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-5-4 下午02:18:45
	 */
	@Override
    public void terminatElement() {
		if (kernel!=null) {
            try {
                kernel.close();
            }catch(Exception e) {}
            kernel = null;
        }
		getLog().sqlLog("[CLOSED]");
	}
	
	/**
	 * 设置验证数据库语句
	 * 刘虻
	 * 2011-5-13 下午03:03:59
	 * @param validationQuerySql 验证数据库语句
	 */
	protected void setValidationQuerySql(String validationQuerySql) {
		this.validationQuerySql = validationQuerySql;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2011-5-13 下午03:06:24
	 */
	@Override
    public boolean checkConnection() {
		if(validationQuerySql==null || validationQuerySql.trim().length()<1) {
			return true; //没有设置语句，返回成功
		}
		ResultSet rs = null; // 记录集
        PreparedStatement stmt = null; // 事务
        try {
            stmt = 
            	getKernel()
            		.prepareStatement(
            				validationQuerySql
            				,ResultSet.TYPE_SCROLL_INSENSITIVE
            				,ResultSet.CONCUR_READ_ONLY);
            rs = stmt.executeQuery();
            return true;
        }catch(Exception e) {
        }finally {
        	try {
        		rs.close();
        	}catch(Exception e2) {}
        	try {
        		stmt.close();
        	}catch(Exception e2) {}
        	try {
        		getKernel().close();
        	}catch(Exception e2) {}
        }
		return false;
	}

	/**
	 * JDK7 中需要覆盖的方法
	 */
	@Override
    public void setSchema(String schema) throws SQLException {}

	/**
	 * JDK7 中需要覆盖的方法
	 */
	@Override
    public String getSchema() throws SQLException {
		return null;
	}

	/**
	 * JDK7 中需要覆盖的方法
	 */
	@Override
    public void abort(Executor executor) throws SQLException {}

	/**
	 * JDK7 中需要覆盖的方法
	 */
	@Override
    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {}

	/**
	 * JDK7 中需要覆盖的方法
	 */
	@Override
    public int getNetworkTimeout() throws SQLException {
		return 0;
	}
}
